import type { FC } from "react";

export type NestFilterOperator =
  | "="
  | "!="
  | ">"
  | ">="
  | "<"
  | "<="
  | "in"
  | "not in"
  | "between"
  | "contain"
  | "not contain"
  | "starts with"
  | "ends with"
  | "is null"
  | "regexp"
  | "subnet";

export type NestFilterJoint = "AND" | "OR";

export type NestFilterFieldType = "string" | "number" | "boolean";

export type NestFilterFieldValue = string | number | boolean | undefined;

type NestFilterFieldComponent =
  | "input"
  | "input_array"
  | "select"
  | "date"
  | "datetime"
  | string
  | FC<{
      value: any;
      showError?: boolean;
      type: NestFilterFieldType;
      operators?: Array<string>;
      disabled?: boolean;
      onChange: (v: any) => void;
    }>;

export type NestFilterOptions = Array<{
  label: string;
  value: string | number;
}>;

export type NestFilterFields = Array<NestFilterField>;

export interface NestFilterChangeHandler {
  (seq: number, joint: NestFilterJoint, conditions: NestFilterConditions): void;
}

export type NestFilterField = {
  key: string;
  label: string;
  operators?: Array<NestFilterOperator>;
  type: NestFilterFieldType;
  component: NestFilterFieldComponent;
  valueLabel?: (v: Array<string | number>) => any;
  options?: ((v?: string) => Promise<NestFilterOptions>) | NestFilterOptions;
};

export type NestFilterConditions = Array<
  | {
      joint: NestFilterJoint;
      condition: NestFilterCondition;
    }
  | {
      joint: NestFilterJoint;
      conditions: NestFilterConditions;
    }
>;

export type NestFilterCondition = {
  key: string;
  operator: NestFilterOperator;
  value: Array<NestFilterFieldValue>;
};

export type NestFilterConditionItemValue = Partial<
  NestFilterCondition & { joint: NestFilterJoint }
>;
